﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace SuperQuery
{
    /// <summary>
    /// Interaction logic for DBListUpgrade.xaml
    /// </summary>
    public partial class DBListUpgrade : Window, Views.IDBListUpgradeView
    {
        /// <summary>
        /// Initialise the Database List Upgrade window
        /// </summary>
        /// <param name="dbListToUpgrade">The list of databases to be upgraded</param>
        public DBListUpgrade(List<Models.Database> dbListToUpgrade)
            : this()
        {
            // Hookup the data context for data binding
            DataContext = this;

            m_Presenter = new Presenters.DBListUpgradePresenter(this, dbListToUpgrade);

            m_UpgradeComplete = false;
        }

        /// <summary>
        /// Initialise the Database Lust Upgrade window
        /// </summary>
        private DBListUpgrade()
        {
            InitializeComponent();
        }

        #region Implemetation of IDBListUpgrade

        /// <summary>
        /// A dictionary of server plugins available for use
        /// </summary>
        public Dictionary<Guid, string> AvailableServerPlugins
        {
            get
            {
                return (Dictionary<Guid, string>)GetValue(AvailableServerPluginsProperty);
            }
            set
            {
                SetValue(AvailableServerPluginsProperty, value);
            }
        }

        /// <summary>
        /// The ID of the selected server plug in
        /// </summary>
        public Guid SelectedServerPluginID
        {
            get
            {
                Guid result = Guid.Empty;

                if ((lstServerPlugins.SelectedItem != null) && (lstServerPlugins.SelectedItem is KeyValuePair<Guid, string>))
                {
                    // An item in the list is selected so return the plugin id (which is the key)
                    KeyValuePair<Guid, string> selectedPlugin = (KeyValuePair<Guid, string>)lstServerPlugins.SelectedItem;
                    result = selectedPlugin.Key;
                }

                return result;
            }
            set
            {
                // Find the server plug in that goes with the provided id
                if (AvailableServerPlugins.Keys.Contains(value))
                {
                    KeyValuePair<Guid, string> plugIn = AvailableServerPlugins.Where(x => x.Key == value).FirstOrDefault();

                    // If we found an item then select it in the list
                    lstServerPlugins.SelectedItem = plugIn;
                }
            }
        }

        /// <summary>
        /// Using a DependencyProperty as the backing store for AvailableServerPlugins.  This enables animation, styling, binding, etc...
        /// </summary>
        private static readonly DependencyProperty AvailableServerPluginsProperty =
            DependencyProperty.Register("AvailableServerPlugins", typeof(Dictionary<Guid, string>), typeof(DBListUpgrade), new UIPropertyMetadata(null));


        #endregion

        /// <summary>
        /// When the OK button is clicked, upgrade the databases and close the window
        /// </summary>
        /// <param name="sender">Who raised the event</param>
        /// <param name="e">Details about th event</param>
        private void btnOK_Click(object sender, RoutedEventArgs e)
        {
            m_Presenter.UpgradeDBList();
            m_UpgradeComplete = true;
            Close();
        }

        /// <summary>
        /// Presenter for this window
        /// </summary>
        private Presenters.DBListUpgradePresenter m_Presenter;

        /// <summary>
        /// The user has clicked the cancel button
        /// </summary>
        /// <param name="sender">Who raised the event</param>
        /// <param name="e">Details about th eevent</param>
        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            m_UpgradeComplete = false;
            Close();
        }

        /// <summary>
        /// The user has tried to close the dialog
        /// </summary>
        /// <param name="sender">Who raised the event</param>
        /// <param name="e">Details about the event</param>
        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            // Make sure the user can close the dialog
            if (!AllowClose())
            {
                e.Cancel = true;
            }
        }

        /// <summary>
        /// Check to see if the user can close the dialog
        /// </summary>
        /// <returns>True if the user is allowed to close, false otherwise</returns>
        private bool AllowClose()
        {
            bool result = true;

            if (!m_UpgradeComplete)
            {
                // This user has clicked cancel without doing an upgrade, warn them about what this means and ask
                // if they really want to continue
                MessageBoxResult msgResult = MessageBox.Show("Cancelling the upgrade process might mean queries fail when run against this database list. Are you sure?",
                    "Cancel Upgrade", MessageBoxButton.YesNo, MessageBoxImage.Question);

                result = (msgResult == MessageBoxResult.Yes);
            }

            return result;
        }

        /// <summary>
        /// If an item in the list is double clicked then select it
        /// </summary>
        /// <param name="sender">Who raised the event</param>
        /// <param name="e">Details about the event</param>
        private void lstServerPlugins_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            if (lstServerPlugins.SelectedItem != null)
            {
                m_Presenter.UpgradeDBList();
                m_UpgradeComplete = true;
                Close();
            }
        }

        /// <summary>
        /// Flag to say whther the upgrade was completed
        /// </summary>
        private bool m_UpgradeComplete;
    }
}
